package com.dek.ssm.ch2.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.junit.Test;

/**
 * 	在 JDK 动态代理中，要实现代理逻辑类必须去实现 java.lang.reflect.InvocationHandler
 *	接口，它里面定义了 一个 invoke 方法，并提供接口数组用于下挂代理对象
 * @author liuxiaodong
 *
 */
public class JdkProxyExample implements InvocationHandler {
	
	// 真实对象
	private Object target = null;
	
	/**
	 *  建立代理对象和真实对象的代理关系，并返回代理对象
	 * @param target
	 * @return 代理对象
	 */
	public Object bind(Object target) {
		this.target = target;
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
	}
	
	/**
	 *   代理方法逻辑
	 */
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("进入代理逻辑方法");
		System.out.println("在调度真实对象之前的服务");
		Object object = method.invoke(target, args); //相当于调用 sayHelloWorld方法
		System.out.println("在调度真实对象之后 的服务");
		return object;
	}
	
	
	@Test
	public void testJdkProxy() {
		JdkProxyExample jdk = new JdkProxyExample();
		// 绑定关系，因为挂在接口 HelloWorld 下，所以声明代理对象 HelloWorld proxy
		HelloWorld proxy = (HelloWorld) jdk.bind(new HelloWorldImpl());
		// 注意 ，此时 HelloWorld 对象己经是一个代理对象，它会进入代理的逻辑方法 invoke 里
		proxy.sayHelloWorld();
		
	}
	
	
	
}
